﻿//==============================================================================  
//Copyright (C) 2012-2015 9UN.ORG. All rights reserved. 
//GUID：46172595-6b69-4526-b9da-426d663f5b05
//CLR Version: 4.0.30319.18033
//Code Author：Kevin Wang
//Contact：Email(Admin@9un.org),QQ(265382 or 74344)
//Filename：MediaInfoHelper
//Namespace：RuanRang.Media.Core.MediaInfo
//Functions：MediaInfoHelper  
//Created by Kevin Wang at 2013/2/2 23:05:09 http://blog.9un.org
//============================================================================== 

using System;
using System.Collections.Generic;
using System.IO;
using RuanRang.Media.MediaInfo.Enums;

namespace RuanRang.Media.MediaInfo
{
    /// <summary>
    /// Dummy helper for manipulations with MediaInfo library over <see cref="MediaInfoLibrary"/> interfaces.
    /// </summary>
    public static class MediaInfoHelper
    {
        private static readonly Dictionary<string, KeyValuePair<DateTime, BasicVideoInformation>> Information = new Dictionary<string, KeyValuePair<DateTime, BasicVideoInformation>>();

        /// <summary>
        /// Gets basic information about file using appropriate library instance.
        /// Library will be unloaded after execution.
        /// </summary>
        /// <param name="fileName">Full path to the file.</param>
        public static BasicVideoInformation GetBasicVideoInfo(string fileName)
        {
            using (var mediaInfoLibrary = new MediaInfoLibrary())
            {
                return GetBasicVideoInfo(mediaInfoLibrary, fileName);
            }
        }

        /// <summary>
        /// Gets basic information about file using specified library instance.
        /// </summary>
        /// <param name="mediaInfoLibrary"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static BasicVideoInformation GetBasicVideoInfo(MediaInfoLibrary mediaInfoLibrary, string fileName)
        {
            if (fileName == null)
                throw new ArgumentNullException("fileName");
            if (!File.Exists(fileName))
                throw new FileNotFoundException("File not found.", fileName);
            //
            if (Information.ContainsKey(fileName))
            {
                var pair = Information[fileName];
                var time = File.GetLastWriteTimeUtc(fileName);
                if (pair.Key == time)
                {
                    return pair.Value;
                }
                Information.Remove(fileName);
            }
            //
            BasicVideoInformation res;
            //
            var utc = File.GetLastWriteTimeUtc(fileName);
            mediaInfoLibrary.OpenFile(fileName);
            //
            try
            {
                res.FileName = fileName;
                //
                var fileSizeString = mediaInfoLibrary.Get(StreamKind.General, 0, "FileSize");
                res.FileSize = String.IsNullOrEmpty(fileSizeString) ? 0 : Convert.ToInt32(fileSizeString);
                //
                var durationString = mediaInfoLibrary.Get(StreamKind.General, 0, "Duration");
                res.DurationMilliseconds = String.IsNullOrEmpty(durationString) ? 0 : Convert.ToInt32(durationString);
                //
                res.VideoFormat = mediaInfoLibrary.Get(StreamKind.General, 0, "Format") ?? String.Empty;
                res.VideoCodec = mediaInfoLibrary.Get(StreamKind.Video, 0, "Codec") ?? String.Empty;
                res.AudioCodec = mediaInfoLibrary.Get(StreamKind.Audio, 0, "Codec") ?? String.Empty;
                //
                var widthStr = mediaInfoLibrary.Get(StreamKind.Video, 0, "Width");
                res.Width = string.IsNullOrEmpty(widthStr) ? 0 : Convert.ToInt32(widthStr);
                //
                var heightStr = mediaInfoLibrary.Get(StreamKind.Video, 0, "Height");
                res.Height = string.IsNullOrEmpty(heightStr) ? 0 : Convert.ToInt32(heightStr);
                //
                var bitrateStr = mediaInfoLibrary.Get(StreamKind.Video, 0, "BitRate");
                res.Bitrate = string.IsNullOrEmpty(bitrateStr) ? 0 : Convert.ToInt32(bitrateStr);
                //
                var fpsStr = mediaInfoLibrary.Get(StreamKind.Video, 0, "FrameRate");
                res.Fps = string.IsNullOrEmpty(fpsStr) ? 0d : Convert.ToDouble(fpsStr.Replace('.', ','));
                //
            }
            finally
            {
                mediaInfoLibrary.CloseFile();
            }
            //
            Information.Add(fileName, new KeyValuePair<DateTime, BasicVideoInformation>(utc, res));
            return res;
        }
    }
}